package org.bintrotter.contentmanager;

public class Block {

	public static final Block Set  = new Block(true);
	public static final Block Nill = new Block(false);
	
	public Block child[];
	
	public Block() {
		child = new Block[2];
		child[0] = child[1] = Nill;
	}
	public Block(boolean leaftype) {
		child = new Block[2];
		child[0] = child[1] = this;
	}
	public Block( Block b1, Block b2) {
		
		child = new Block[2];
		child[0] = b1;
		child[1] = b2;
	}
	
	public boolean isLeaf() {
		
		return this == Set || this == Nill;
	}
	
	public Block optimise() {
		
		if(this == Set || this == Nill)
			return this;
		
		int same = 0;
		Block b;
		
		for(int i=0; i<child.length; ++i)
			if((b = child[i].optimise())!=null) 
				if(child[0] == (child[i] = b))
					++same;
		
		if(same == child.length)
			return child[0];
		
		return null;
	}
	
	public boolean interested(Block rhv) {
		
		Block lh = this.optimise();
		
		if(lh==Set)
			return false; // we have everything, not interested.
		
		Block rh = rhv.optimise(); 
		
		if(rh==Nill)
			return false; // rhv has nothing, not interested.
		
		if(lh==Nill) 
			return true; // we have nothing, rhv has at least one.
		
		if(lh==null && rh==Set)
			return true; // we have some, but rhv has everything.
		
		// both this and rhv have some, inspect lower levels.
		for(int i=0;i<child.length;++i)
			if(child[i].interested(rhv.child[i]))
				return true;
		
		return false;
	}
	
	public long countNodes() {
		
		if(isLeaf())
			return 0;
		
		long tot = 1;
		for(int i=0;i<child.length;++i)
			tot += child[i].countNodes();
		
		return tot;
	}
	
	public long countLeaves() {
		 
		if(isLeaf())
			return 1;
		
		long tot = 0;
		for(int i=0;i<child.length;++i)
			tot += child[i].countLeaves();
		
		return tot;
	}
	
	public void dump(int depth) {
		
		if(isLeaf()) {
			while(depth-->0)
				System.out.print("-");
			
			if(this==Set)
				System.out.println("S");
			else
				System.out.println("N");
		}
		else
			for(int i=0;i<child.length;i++)
				child[i].dump(depth+1);
	}
}

